﻿using Cysharp.Threading.Tasks;
using System;
using UniRx;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;

/// <summary>
/// 场景加载器
/// </summary>
public static class SceneManager
{
    /// <summary>
    /// 场景过渡界面淡入淡出持续时间
    /// </summary>
    public const float LOADING_FADE_DURATION = 0.6f;

    /// <summary>
    /// 刻意加载延迟
    /// </summary>
    private const float INTENTIONAL_DELAY = 0.35f;

    /// <summary>
    /// 当前场景
    /// </summary>
    public static Scene currentScene => UnityEngine.SceneManagement.SceneManager.GetActiveScene();

    /// <summary>
    /// 加载信息
    /// </summary>
    public static AsyncOperationHandle<SceneInstance> loadingHandle { get => m_LoadingHandle.Value; private set => m_LoadingHandle.Value = value; }
    private static ReactiveProperty<AsyncOperationHandle<SceneInstance>> m_LoadingHandle = new ReactiveProperty<AsyncOperationHandle<SceneInstance>>();
    public static IObservable<AsyncOperationHandle<SceneInstance>> onLoadingHandleChanged => m_LoadingHandle;

    /// <summary>
    /// 开始加载时点
    /// </summary>
    public static IObservable<Unit> onLoadingStart => s_LoadingStartTrigger;
    private static Subject<Unit> s_LoadingStartTrigger = new Subject<Unit>();

    /// <summary>
    /// 过渡遮罩显示完全时点
    /// </summary>
    public static IObservable<Unit> onLoadingMaskEnabled => s_LoadingMaskEnabledTrigger;
    private static Subject<Unit> s_LoadingMaskEnabledTrigger = new Subject<Unit>();

    /// <summary>
    /// 过渡遮罩隐藏开始时点
    /// </summary>
    public static IObservable<Unit> onLoadingMaskDisabled => s_LoadingMaskDisabledTrigger;
    private static Subject<Unit> s_LoadingMaskDisabledTrigger = new Subject<Unit>();

    /// <summary>
    /// 结束加载时点
    /// </summary>
    public static IObservable<Unit> onLoadingEnd => s_LoadingEndTrigger;
    private static Subject<Unit> s_LoadingEndTrigger = new Subject<Unit>();


    /// <summary>
    /// 异步加载场景
    /// </summary>
    public static UniTask LoadSceneAsync(int sceneId, bool showLoadingMask = true)
    {
        return LoadSceneAsync($"Scene_{sceneId}", showLoadingMask);
    }

    /// <summary>
    /// 异步加载场景
    /// </summary>
    public static async UniTask LoadSceneAsync(string sceneName, bool showLoadingMask = true)
    {
        if (!showLoadingMask)
        {
            await Addressables.LoadSceneAsync($"Scenes/{sceneName}.unity", LoadSceneMode.Single, true);
            return;
        }
        s_LoadingStartTrigger.OnNext(Unit.Default);
        await Tools.Delay(LOADING_FADE_DURATION);
        s_LoadingMaskEnabledTrigger.OnNext(Unit.Default);
        await Addressables.LoadSceneAsync("Scenes/Empty.unity", LoadSceneMode.Single, true);
        await Tools.Delay(INTENTIONAL_DELAY);
        loadingHandle = Addressables.LoadSceneAsync($"Scenes/{sceneName}.unity", LoadSceneMode.Single, false);
        var newSceneInstance = await loadingHandle;
        await Tools.Delay(INTENTIONAL_DELAY);
        await newSceneInstance.ActivateAsync();
        s_LoadingMaskDisabledTrigger.OnNext(Unit.Default);
        await Tools.Delay(LOADING_FADE_DURATION);
        s_LoadingEndTrigger.OnNext(Unit.Default);
        loadingHandle = default;
    }
}